package com.tsfyun.scm.service.impl.system;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.constant.CacheConstant;
import com.tsfyun.common.base.enums.BizParamEnum;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.extension.OrderItem;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.system.SysParamDTO;
import com.tsfyun.scm.entity.system.SysParam;
import com.tsfyun.scm.mapper.system.SysParamMapper;
import com.tsfyun.scm.service.system.ISysParamService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.system.SysParamVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *  参数配置服务实现类
 * </p>
 *

 * @since 2020-04-15
 */
@Service
public class SysParamServiceImpl extends ServiceImpl<SysParam> implements ISysParamService {

    @Autowired
    private SysParamMapper sysParamMapper;

    @CacheEvict(value = CacheConstant.SYSTEM_CONFIG_MAP,allEntries = true,beforeInvocation = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SysParamDTO dto) {
        SysParam sysParam = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(sysParam),new ServiceException("参数配置信息不存在"));
        TsfPreconditions.checkArgument(!sysParam.getLocking(),new ServiceException("参数配置已被锁定禁止修改"));
        sysParam.setId(dto.getId());
        sysParam.setVal(dto.getVal());
        sysParam.setRemark(StringUtils.isEmpty(dto.getRemark()) ? BizParamEnum.of(dto.getId()).getName() : dto.getRemark());
        try {
            sysParamMapper.update(dto, SecurityUtil.getCurrentPersonIdAndName());
        } catch (DuplicateKeyException e) {
            throw new ServiceException("参数名已经存在");
        }
    }

    @CacheEvict(value = CacheConstant.SYSTEM_CONFIG_MAP,allEntries = true,beforeInvocation = true)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDisabled(String id, Boolean disabled) {
        SysParam sysParam = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(sysParam),new ServiceException("参数配置信息不存在"));
        TsfPreconditions.checkArgument(!sysParam.getLocking(),new ServiceException("参数配置已被锁定禁止修改"));

        SysParam update = new SysParam();
        update.setDisabled(disabled);
        sysParamMapper.updateByExampleSelective(update, Example.builder(SysParam.class).where(
                TsfWeekendSqls.<SysParam>custom().andEqualTo(false,SysParam::getId, id)).build()
        );
    }

    @Override
    public SysParamVO getById(String id) {
        SysParamVO  sysParam = beanMapper.map(super.getById(id),SysParamVO.class);
        TsfPreconditions.checkArgument(Objects.nonNull(sysParam),new ServiceException("参数配置信息不存在"));
        return sysParam;
    }

    @Override
    @Cacheable(value = CacheConstant.SYSTEM_CONFIG_MAP,key = "'ALLMAP'")
    public Map<String,SysParamVO> obtainAllParamMap(){
        List<SysParam> sysParams = list();
        Map<String,SysParamVO> resultMap = beanMapper.mapAsList(sysParams,SysParamVO.class).stream().collect(Collectors.toMap(SysParamVO::getId,Function.identity()));
        return resultMap;
    }

    @Override
    public PageInfo<SysParam> pageList(SysParamDTO sysParamDTO) {
        TsfWeekendSqls sqls = TsfWeekendSqls.<SysParam>custom()
                .andEqualTo(true,SysParam::getId,sysParamDTO.getId())
                .andLike(true,SysParam::getVal,sysParamDTO.getVal())
                .andLike(true,SysParam::getRemark,sysParamDTO.getRemark())
                .andEqualTo(true,SysParam::getDisabled,sysParamDTO.getDisabled());
        PageInfo<SysParam> pageInfo = super.pageList(sysParamDTO.getPage(),sysParamDTO.getLimit(),sqls, Lists.newArrayList(OrderItem.asc("id")));
        return pageInfo;
    }

    @Override
    public List<SysParamVO> getByIds(BizParamEnum... paramEnums) {
        if(ArrayUtil.isEmpty(paramEnums)) {
            return null;
        }
        List<String> ids = Arrays.asList(paramEnums).stream().map(BizParamEnum::getCode).collect(Collectors.toList());
        List<SysParam> sysParams = sysParamMapper.getByIds(ids);
        return CollUtil.isNotEmpty(sysParams) ? beanMapper.mapAsList(sysParams,SysParamVO.class) : null;
    }
}
